#include "SrcFilesWatcher.h"
#include "Poco\Util\Application.h"
#include "Poco\Path.h"
#include "Poco\RecursiveDirectoryIterator.h"
#include "Poco\File.h"
#include <string>
#include "Util.h"
#include "Cryptoer.h"
#include "Poco\Delegate.h"
using Poco::Util::Application;
using Poco::Path;
using Poco::File;

using Poco::SimpleRecursiveDirectoryIterator;
using Poco::SiblingsFirstRecursiveDirectoryIterator;
using Poco::delegate;
SrcFilesWatcher::SrcFilesWatcher()
{
}


SrcFilesWatcher::~SrcFilesWatcher()
{
	for (std::map<std::string, DirWatcher*>::iterator it = watchers.begin(); it != watchers.end(); ++it) {
		delete it->second;
	}
	watchers.clear();

}

void SrcFilesWatcher::watch()
{
	Application& app = Application::instance();
	Path psrc = Path().absolute().pushDirectory(app.config().getString("src"));
	File f(psrc);
	watchDir(f);

}



void SrcFilesWatcher::onItemAdded(const DirWatcher::DirectoryEvent& ev)
{
	Application& app = Application::instance();
	app.logger().information("file added:%s", ev.item.path());

}


void SrcFilesWatcher::onItemRemoved(const DirWatcher::DirectoryEvent& ev)
{
	Application& app = Application::instance();
	//if (ev.item.isDirectory())//ERROR, item has been removed, isDirectory() throw exception.
	//removeDir(ev.item);
	app.logger().information("file removed:%s",ev.item.path());
	if (ev.item.exists() && ev.item.isFile()) {
		if (ev.item.getSize() > 0) {
			File srcs=Util::getSrcsFile(ev.item);
			if (srcs.exists())
			{
				srcs.remove();
			}
		}
	}
}


void SrcFilesWatcher::onItemModified(const DirWatcher::DirectoryEvent& ev)
{
	Application& app = Application::instance();
	if (ev.item.exists() && ev.item.isFile()) {
		if (ev.item.getSize() > 0) {
			Util::getCurrentCryptoer()->encodeFile(ev.item);
			app.logger().information("file changed:%s",ev.item.path());

		}
	}
}


void SrcFilesWatcher::watchDir(const Poco::File & f)
{
	Application& app = Application::instance();
	std::map<std::string, DirWatcher*>::iterator it = watchers.find(f.path());
	if (it != watchers.end())return;
	DirWatcher * dw = new DirWatcher(f.path(), DirWatcher::DW_FILTER_ENABLE_ALL, 5);
	dw->itemAdded += delegate(this, &SrcFilesWatcher::onItemAdded);
	dw->itemRemoved += delegate(this, &SrcFilesWatcher::onItemRemoved);
	dw->itemModified += delegate(this, &SrcFilesWatcher::onItemModified);
	watchers.insert(std::make_pair(f.path(), dw));
	app.logger().warning("%s watcher added", f.path());
}

void SrcFilesWatcher::unwatchDir(const Poco::File & f)
{
	Application& app = Application::instance();
	std::map<std::string, DirWatcher*>::iterator it;
	for (it = watchers.begin(); it != watchers.end(); ++it) {
		File file(it->first);
		if (!file.exists())
		{
			delete it->second;
			watchers.erase(it);
		}
	}
	app.logger().warning("%s watcher removed", f.path());
}
